package com.acceptable.qucun.generic.util.result;

import com.acceptable.qucun.generic.exception.BaseException;
import com.acceptable.qucun.generic.util.CodeUtil;
import com.acceptable.qucun.generic.util.result.error.BaseErrorResult;
import com.acceptable.qucun.generic.util.result.error.FileErrorResult;
import com.acceptable.qucun.generic.util.result.error.GenericErrorResult;
import com.acceptable.qucun.generic.util.result.error.UserErrorResult;
import com.acceptable.qucun.generic.util.result.success.BaseSuccessResult;
import com.acceptable.qucun.generic.util.result.success.FileSuccessResult;
import com.acceptable.qucun.generic.util.result.success.UserSuccessResult;
import org.springframework.lang.NonNull;

import java.util.HashMap;
import java.util.Map;

public class ResultUtil {
    private static Map<String, BaseErrorResult> allErrorResult;
    private static Map<String, BaseSuccessResult> allSuccessResult;

    public static BaseErrorResult getErrorResultFromAll(String code){
        if(allErrorResult == null)
            allErrorResult = new HashMap<>();
        int actualSize = GenericErrorResult.getResultMap().size() +
                         UserErrorResult.getResultMap().size() +
                         FileErrorResult.getResultMap().size();

        if(allErrorResult.size() != actualSize){
            allErrorResult.putAll(GenericErrorResult.getResultMap());
            allErrorResult.putAll(UserErrorResult.getResultMap());
            allErrorResult.putAll(FileErrorResult.getResultMap());
        }
        return allErrorResult.get(code);
    }

    public static BaseSuccessResult getSuccessResultFromAll(String code){
        if(allSuccessResult == null)
            allSuccessResult = new HashMap<>();
        int actualSize = UserSuccessResult.getResultMap().size() + FileSuccessResult.getResultMap().size();

        if(allSuccessResult.size() != actualSize){
            allSuccessResult.putAll(UserSuccessResult.getResultMap());
            allSuccessResult.putAll(FileSuccessResult.getResultMap());
        }
        return allSuccessResult.get(code);
    }

    public static String error(BaseErrorResult error){
        Map<String, String> errorMap = new HashMap<>();
        if(error != null){
            errorMap.put("msg", error.getMsg());
            errorMap.put("code", error.getCode());
        }
        return CodeUtil.object2String(errorMap);
    }

    public static Map<String, Object> resultMap(@NonNull String[] keys,
                                                @NonNull Object[] values){
        Map<String, Object> resMap = new HashMap<>();
        if (keys.length != values.length){
            throw new BaseException(GenericErrorResult.DATA_LENGTH_NOT_EQUAL_ERROR);
        }

        for (int i = 0; i < keys.length; i++){
            resMap.put(keys[i], values[i]);
        }
        return resMap;
    }

    public static String success(@NonNull String[] keys,
                                 @NonNull Object[] values){
        return CodeUtil.object2String(CodeUtil.base64Encode(resultMap(keys, values)));
    }

    public static String success(BaseSuccessResult success){
        Map<String, Object> successMap = new HashMap<>();
        if(success != null){
            successMap.put("code", success.getCode());
            successMap.put("msg", success.getMsg());
        }
        return CodeUtil.object2String(successMap);
    }

    public static String success(BaseSuccessResult success, String[] keys, Object[] values){
        Map<String, Object> successMap = new HashMap<>();
        if(success != null){
            successMap.put("code", success.getCode());
            successMap.put("msg", success.getMsg());
        }
        if(keys != null && values != null){
            Map<String, Object> dataMap = new HashMap<>();
            for (int i = 0; i < keys.length && i < values.length; i++){
                dataMap.put(keys[i], values[i]);
            }
            successMap.put("data", CodeUtil.base64Encode(dataMap));
        }
        return CodeUtil.object2String(successMap);
    }
}
